#include "../头文件/UserFunction.h"

// 定义全局变量-注册/登录页面
ClickObject registerOrLogin = NONE;

/**
 * @brief 注册页面
 *
 */
void goto_register()
{
    memset(InputAccount, 0, sizeof(InputAccount));
    memset(InputPassword, 0, sizeof(InputPassword));
    smallEyeState = true;
    show_anyjpg(0, 0, ACCOUNTPASSWORD);
    registerOrLogin = REGISTER;
    show_anyjpg(290, 40, LOGO_REGISTER);
}
/**
 * @brief 登录页面
 *
 */
void goto_login()
{
    memset(InputAccount, 0, sizeof(InputAccount));
    memset(InputPassword, 0, sizeof(InputPassword));
    smallEyeState = true;
    show_anyjpg(0, 0, ACCOUNTPASSWORD);
    registerOrLogin = LOGIN;
    show_anyjpg(290, 40, LOGO_LOGIN);
}
/**
 * @brief 用户选择注册或者登录的页面
 *
 */
void select_register_or_login()
{
    // 判断用户点击了哪个页面
    int select_goto;
    if (objectselection == USER)
        select_goto = get_click_type();
    // 点击这个范围跳转到注册页面
    if (select_goto == REGISTER)
        goto_register();
    // 点击这个范围跳转到登录页面
    if (select_goto == LOGIN)
        goto_login();
}
/**
 * @brief 返回按键(进入注册/登录页面后)
 *
 * 返回选择注册/登录页面
 */
void return_key()
{
    if (!isChangePassword)
        goto_user(USER_IMAGE);
    else
    {
        memset(InputOldPassword, 0, sizeof(InputOldPassword));
        memset(InputNewPassword, 0, sizeof(InputNewPassword));
        smallEyeState = true;
        close_functions_window();
        functions();
    }
}
/**
 * @brief 键盘点击按键
 *
 * @return char 返回点击的数字字符
 */
char keyboard_touch(Flag key)
{
    switch (key)
    {
    case ZERO:
        return '0';
    case ONE:
        return '1';
    case TWO:
        return '2';
    case THREE:
        return '3';
    case FOUR:
        return '4';
    case FIVE:
        return '5';
    case SIX:
        return '6';
    case SEVEN:
        return '7';
    case EIGHT:
        return '8';
    case NINE:
        return '9';
    case POINT:
        return '.';
    default:
        return (char)key;
    }
}
/**
 * @brief 填充数据
 */
void input_data()
{
    if (!isChangePassword)
        while (1)
        {
            // 显示账号密码画布
            show_account_password_canvas();
            // 显示小眼睛
            small_eye(smallEyeState);
            // 看点击的位置是什么按键
            Flag select = all_click_event(false);
            // 记录点击的账号还是密码
            Flag currentfill;

            // 点击账号密码画布就弹出键盘
            if (select == ACCOUNT || select == PASSWORD)
            {
                // 获取当前点击的文本框
                currentfill = select;
                show_keyboard();
            }
            // 点击键盘旁边两个位置就关闭键盘
            else if (select == CLOSEKEYBOARD)
                close_keyboard();
            // 点击左上角返回键 就退回用户页面
            else if (select == RETURN)
            {
                return_key();
                break;
            }
            // 点击小眼睛
            else if (select == SMALLEYE)
            {
                smallEyeState = !smallEyeState;
            }
            // 将数字导入数组
            else if (keyBoardShow)
            {
                // 将数字转成字符
                char data = keyboard_touch(select);
                // 判断该字符是什么字符
                // 如果传入的是清除键
                if (data == CLEAR)
                    clear_data(clickobject);
                // 如果传入的是删除键
                else if (data == DELETE)
                    delete_data(clickobject);
                // 如果传入的是确认键
                else if (data == CONFIRM)
                {
                    // 测试语句(减少输入账号的流程)
                    // sprintf(InputAccount, "%s", "1234567");
                    // sprintf(InputPassword, "%s", "123456");
                    // 测试end
                    confirm_data(registerOrLogin);
                    break;
                }
                else
                {
                    // 如果传入的是数字键
                    // 判断当前的填框是什么
                    if (currentfill == ACCOUNT)
                        sprintf(InputAccount, "%s%c", InputAccount, data);
                    else if (currentfill == PASSWORD)
                        sprintf(InputPassword, "%s%c", InputPassword, data);
                }
            }
        }
    else
        while (1)
        {
            // 显示旧密码新密码画布
            if (strlen(InputOldPassword) != 0)
                show_text(253, 30, 4, getColor(255, 16, 136, 221), 30, 2, 2, InputOldPassword, getColor(0, 0, 0, 0), 600, 800 * 98 + 265);
            else
                show_text(253, 30, 4, getColor(255, 16, 136, 221), 30, 2, 2, "输入旧密码", getColor(0, 16, 136, 128), 600, 800 * 98 + 265);

            if (strlen(InputNewPassword) != 0)
            {
                char *current_password = hide_password(InputNewPassword);
                show_text(253, 30, 4, getColor(255, 16, 136, 221), 30, 2, 2, current_password, getColor(0, 0, 0, 0), 600, 800 * 133 + 265);
                // 打印完后释放内存空间
                // 当前的密码指针不等于密码字符数组 (隐藏密码) ---> 释放内存
                if (current_password != InputNewPassword)
                    free(current_password);
            }
            else
                show_text(253, 30, 4, getColor(255, 16, 136, 221), 30, 2, 2, "输入新密码", getColor(0, 16, 136, 128), 600, 800 * 133 + 265);

            // 显示小眼睛
            small_eye(smallEyeState);
            // 看点击的位置是什么按键
            Flag select = all_click_event(false);
            // 记录点击的账号还是密码
            Flag currentfill;

            // 点击账号密码画布就弹出键盘
            if (select == ACCOUNT || select == PASSWORD)
            {
                // 获取当前点击的文本框
                currentfill = select;
                show_keyboard();
            }
            // 点击键盘旁边两个位置就关闭键盘
            else if (select == CLOSEKEYBOARD)
                close_keyboard();
            // 点击左上角返回键 就退回用户页面
            else if (select == RETURN)
            {
                return_key();
                break;
            }
            // 点击小眼睛
            else if (select == SMALLEYE)
            {
                smallEyeState = !smallEyeState;
            }
            // 将数字导入数组
            else if (keyBoardShow)
            {
                // 将数字转成字符
                char data = keyboard_touch(select);
                // 判断该字符是什么字符
                // 如果传入的是清除键
                if (data == CLEAR)
                    clear_data(clickobject);
                // 如果传入的是删除键
                else if (data == DELETE)
                    delete_data(clickobject);
                // 如果传入的是确认键
                else if (data == CONFIRM)
                {
                    confirm_data(registerOrLogin);
                    break;
                }
                else
                {
                    // 如果传入的是数字键
                    // 判断当前的填框是什么
                    if (currentfill == ACCOUNT)
                        sprintf(InputOldPassword, "%s%c", InputOldPassword, data);
                    else if (currentfill == PASSWORD)
                        sprintf(InputNewPassword, "%s%c", InputNewPassword, data);
                }
            }
        }
}
/**
 * @brief 开启或者关闭小眼睛(显示/隐藏密码)
 *
 * @param eyeState 小眼睛的状态
 */
void small_eye(bool eyeState)
{
    if (eyeState)
        show_anyjpg(525, 130, OPEN_SMALL_EYE);
    else if (!eyeState)
        show_anyjpg(525, 130, CLOSE_SMALL_EYE);
}
/**
 * @brief 隐藏密码 (用*代替)
 *
 * @param password 传入的密码
 */
char *hide_password(char *password)
{
    if (!smallEyeState)
    {
        int length = strlen(password);
        // 分配一个密码长度+1 个 char*(8字节)的内存空间
        char *hide = calloc(length + 1, sizeof(char *));
        if (hide == NULL)
        {
            // 处理分配失败的情况
            return NULL;
        }
        // 将密码显示为*
        memset(hide, '*', strlen(password));
        // 密码的结束符
        hide[length] = '\0';
        return hide;
    }
    else
        return password;
}

/**
 * @brief 将UserData结构体写入文件
 *
 * @param user UserData数据
 */
bool StoreData(UserData *userdata)
{
    FILE *file = fopen(USER_DATA, "r"); // 以读模式打开文件
    if (file == NULL)
    {
        perror("无法打开文件");
        file = fopen(USER_DATA, "w"); // 文件不存在则创建
        if (file == NULL)
        {
            perror("无法创建文件");
            return false;
        }
        fclose(file);
        file = fopen(USER_DATA, "r"); // 重新以读模式打开
        if (file == NULL)
        {
            perror("重新打开文件失败");
            return false;
        }
    }
    // 临时存储文件中的所有用户数据
    UserData *users = NULL;
    int user_count = 0;
    char line[256];
    UserData current_user;
    init_user_data(&current_user); // 初始化 current_user

    // 读取文件中的所有用户数据
    while (fgets(line, sizeof(line), file) != NULL)
    {
        // 防止文本出错 (我清空用:%d 会占一个字符 但是为空的)
        if (strlen(line) == 0)
        {
            printf("这里退出fgets循环\n");
            break;
        }

        // 去掉换行符
        line[strcspn(line, "\n")] = '\0';
        // 解析账号
        if (strstr(line, "Account: ") == line)
        {
            current_user.Account = strdup(line + 9);
        }
        // 解析密码
        else if (strstr(line, "Password: ") == line)
        {
            current_user.Password = strdup(line + 10);
        }
        // 解析注册时间
        else if (strstr(line, "RegisterTime: ") == line)
        {
            current_user.RegisterTime = strdup(line + 14);
        }
        // 解析上次登录时间
        else if (strstr(line, "LastLoginTime: ") == line)
        {
            current_user.LastLoginTime = strdup(line + 15);
        }
        // 解析手机号
        else if (strstr(line, "Phone: ") == line)
        {
            current_user.Phone = strdup(line + 7);
        }
        // 解析充电卡编号
        else if (strstr(line, "ChargingCardId: ") == line)
        {
            current_user.ChargingCard.CardId = strdup(line + 16);
        }
        // 解析充电卡金额
        else if (strstr(line, "Money: ") == line)
        {
            sscanf(line + 6, "%lf", &current_user.ChargingCard.Money);
        }
        // 解析充电卡有效期
        else if (strstr(line, "ChargingCardValidity: ") == line)
        {
            current_user.ChargingCard.Validity = strdup(line + 22);
        }
        // 用户数据结束
        else if (strstr(line, "----------------------------------------------------") == line)
        {
            UserData *new_users = realloc(users, (user_count + 1) * sizeof(UserData));
            if (new_users == NULL)
            {
                perror("realloc failed");
                for (int i = 0; i < user_count; i++)
                {
                    free_user_data(&users[i]);
                }
                free(users);
                fclose(file);
                return false;
            }
            users = new_users;
            users[user_count++] = current_user;
            init_user_data(&current_user); // 重新初始化 current_user
        }
    }
    fclose(file);
    // 查找用户数据是否存在
    int index = find_user(userdata->Account, users, user_count);

    if (index != -1)
    {
        // 在注册页面的时候 检测到数据库也有账号 返回错误
        if (registerOrLogin == REGISTER)
        {
            show_anyjpg(265, 185, ALREADY_EXIST_ACCOUNT);
            return false;
        }
        // 如果存在，比较数据是否发生变化
        if (strcmp(users[index].Password, userdata->Password) != 0 ||
            strcmp(users[index].RegisterTime, userdata->RegisterTime) != 0 ||
            strcmp(users[index].LastLoginTime, userdata->LastLoginTime) != 0 ||
            strcmp(users[index].Phone, userdata->Phone) != 0 ||
            strcmp(users[index].ChargingCard.CardId, userdata->ChargingCard.CardId) != 0 ||
            users[index].ChargingCard.Money != userdata->ChargingCard.Money ||
            strcmp(users[index].ChargingCard.Validity, userdata->ChargingCard.Validity) != 0)
        {
            // 数据发生变化，释放旧数据的内存并更新
            free_user_data(&users[index]);
            users[index] = *userdata;
        }
        else
        {
            // 数据未发生变化，直接返回
            for (int i = 0; i < user_count; i++)
            {
                free_user_data(&users[i]);
            }
            free(users);
            return true;
        }
    }
    else
    {
        // 如果不存在，追加新的用户数据
        UserData *new_users = realloc(users, (user_count + 1) * sizeof(UserData));
        if (new_users == NULL)
        {
            perror("realloc failed");
            for (int i = 0; i < user_count; i++)
            {
                free_user_data(&users[i]);
            }
            free(users);
            return false;
        }
        users = new_users;
        users[user_count++] = *userdata;
        init_user_data(&current_user); // 确保 current_user 被重新初始化
    }

    // 将更新后的用户数据写入文件
    file = fopen(USER_DATA, "w"); // 以写模式打开文件，覆盖原内容
    if (file == NULL)
    {
        perror("无法打开文件");
        return false;
    }

    for (int i = 0; i < user_count; i++)
    {
        fprintf(file, "Account: %s\n", users[i].Account);
        fprintf(file, "Password: %s\n", users[i].Password);
        fprintf(file, "RegisterTime: %s\n", users[i].RegisterTime);
        fprintf(file, "LastLoginTime: %s\n", users[i].LastLoginTime);
        fprintf(file, "Phone: %s\n", users[i].Phone);
        fprintf(file, "ChargingCardId: %s\n", users[i].ChargingCard.CardId);
        fprintf(file, "Money: %lf\n", users[i].ChargingCard.Money);
        fprintf(file, "ChargingCardValidity: %s\n", users[i].ChargingCard.Validity);
        fprintf(file, "----------------------------------------------------\n");
    }

    fclose(file);

    // 释放所有用户数据的内存
    for (int i = 0; i < user_count; i++)
    {
        free_user_data(&users[i]);
    }
    free(users);
    return true;
}
/**
 * @brief 获取保存在数据库的用户信息
 *
 * @param Account 用户账号
 * @return UserData 用户信息结构体
 */
UserData *GetUserData(const TextType Account)
{
    FILE *file = fopen(USER_DATA, "r"); // 以读模式打开文件
    if (file == NULL)
    {
        perror("无法打开文件");
        return NULL;
    }

    UserData *user = NULL;
    char line[256];
    UserData current_user;
    init_user_data(&current_user); // 初始化 current_user

    // 读取文件中的所有用户数据
    while (fgets(line, sizeof(line), file) != NULL)
    {
        // 防止文本出错 (我清空用:%d 会占一个字符 但是为空的)
        if (strlen(line) == 0)
        {
            printf("这里退出fgets循环\n");
            break;
        }

        // 去掉换行符
        line[strcspn(line, "\n")] = '\0';

        // 解析账号
        if (strstr(line, "Account: ") == line)
        {
            current_user.Account = strdup(line + 9);
        }
        // 解析密码
        else if (strstr(line, "Password: ") == line)
        {
            current_user.Password = strdup(line + 10);
        }
        // 解析注册时间
        else if (strstr(line, "RegisterTime: ") == line)
        {
            current_user.RegisterTime = strdup(line + 14);
        }
        // 解析上次登录时间
        else if (strstr(line, "LastLoginTime: ") == line)
        {
            current_user.LastLoginTime = strdup(line + 15);
        }
        // 解析手机号
        else if (strstr(line, "Phone: ") == line)
        {
            current_user.Phone = strdup(line + 7);
        }
        // 解析充电卡编号
        else if (strstr(line, "ChargingCardId: ") == line)
        {
            current_user.ChargingCard.CardId = strdup(line + 16);
        }
        // 解析充电卡金额
        else if (strstr(line, "Money: ") == line)
        {
            sscanf(line + 6, "%lf", &current_user.ChargingCard.Money);
        }
        // 解析充电卡有效期
        else if (strstr(line, "ChargingCardValidity: ") == line)
        {
            current_user.ChargingCard.Validity = strdup(line + 22);
        }
        // 用户数据结束
        else if (strstr(line, "----------------------------------------------------") == line)
        {
            // 检查当前用户的账号是否匹配
            if (strcmp(current_user.Account, Account) == 0)
            {
                // 绑定充电卡的账号和用户账号
                current_user.ChargingCard.Account = malloc(sizeof(char) * strlen(current_user.Account) + 1);
                strcpy(current_user.ChargingCard.Account, Account);
                // 找到匹配的用户，分配内存并返回
                user = malloc(sizeof(UserData));
                if (user == NULL)
                {
                    perror("malloc failed");
                    free_user_data(&current_user);
                    fclose(file);
                    return NULL;
                }
                *user = current_user;
                fclose(file);
                return user;
            }
            // 如果不匹配，释放当前用户的内存
            free_user_data(&current_user);
            init_user_data(&current_user); // 重新初始化 current_user
        }
    }

    fclose(file);

    // 如果没有找到匹配的用户，返回 NULL
    return NULL;
}